蓝桥杯 历届试题 合根植物 JAVA

问题描述
  w星球的一个种植园,被分成 m * n 个小格子(东西方向m行,南北方向n列)。每个格子里种了一株合根植物。
  这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成为一体。


  如果我们告诉你哪些小格子间出现了连根现象,你能说出这个园中一共有多少株合根植物吗?
输入格式
  第一行,两个整数m,n,用空格分开,表示格子的行数、列数(1<m,n<1000)。
  接下来一行,一个整数k,表示下面还有k行数据(0<k<100000)
  接下来k行,第行两个整数a,b,表示编号为a的小格子和编号为b的小格子合根了。


  格子的编号一行一行,从上到下,从左到右编号。
  比如:5 * 4 的小格子,编号:
  1 2 3 4
  5 6 7 8
  9 10 11 12
  13 14 15 16
  17 18 19 20
样例输入
5 4
16
2 3
1 5
5 9
4 8
7 8
9 10
10 11
11 12
10 14
12 16
14 18
17 18
15 19
19 20
9 13
13 17
样例输出
5
样例说明
  其合根情况参考下图


命名比较Low。 百度上没有java的,只好自己写喽

我的 思路:
遍历每个块,假设1号方块,通过输入,给1号方块可达方块添加进该块的list集合,并且把能到达1号方块的方块也添加进1号方块的list集合。
即有向变无向。
然后就递归方块一条路走到黑,然后count++;
最后输出count就行。

上面的例子:
4->8,7->8, 但是遍历会递归4,到8之后不能到7,但是有7->8. 所以如何把7->8转换为8->7也有路是关键。最终解决方法不难,不过对于萌新来说还是累啊哈哈

备注都在代码上了。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Scanner;
public class Main {
	static Scanner scanf=new Scanner(System.in);
	static HashMap<Integer, Zw> hm=new HashMap<Integer,Zw>();		//hashmap键值对不需要遍历
	static int count=0;	//计数
	public static void main(String[] args) {
		int m=scanf.nextInt();	//行
		int n=scanf.nextInt();		//列
		for (int i = 0; i < m*n; i++) {
			Zw zw=new Zw();
			hm.put(i+1, zw);		//给每个方格一个编号
		}
		int k=scanf.nextInt();	//边数
		for (int i = 0; i < k; i++) {
			int start=scanf.nextInt();	//边的起点	
			int end=scanf.nextInt();		//边的终点
			Zw zw=hm.get(start);	//取出一个点
			zw.to.add(end);	//给该点可达点添加进集合
			Zw zw2=hm.get(end);	//重点!敲黑板     
			zw2.to.add(start);//当该点被可达时也添加进,  即有向改无向
		}
		for (int i = 1; i <=m*n; i++) {
			digui(i,true);	//第一个参数是遍历,第二个表示是最外层递归,最后计数要做判断
		}
		System.out.println(count);//答案
	}
	public static void digui(int i,boolean b){
		if(!hm.get(i).life){	//如果该块没有被走过再进入
			hm.get(i).life=true;	//先设为true表示被走过
			ArrayList<Integer> list=hm.get(i).to;	//得到该块可达路径集合(包括被可达路径)
			Iterator<Integer> iterable= list.iterator();	//迭代
			while (iterable.hasNext()) {	//如果有可达路径进入循环
				int temp=iterable.next();	//得到可达点
					digui(temp,false);	//遍历可达路径的可达路径
			}
			if(b){	//如果是最外层循环结束,即一条路走完。
				count++;
			}
		}
	}
}
class Zw{
	public ArrayList<Integer> to=new ArrayList<Integer>();	//可达路径集合
	boolean life=false;	//该点是否被遍历过
}


这个代码,在蓝桥杯评测不是100%得100分的,需要多提交几次。感觉还可以优化。希望大家多提提意见。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值